package com.google.jessewilson.codesearch.intellij;

import com.google.jessewilson.codesearch.api.QueryRunner;
import com.google.jessewilson.codesearch.api.QueryResponse;
import com.google.jessewilson.codesearch.combining.ResultsCombiner;
import com.google.jessewilson.codesearch.ui.ResultsPanelContext;
import com.google.jessewilson.codesearch.ui.ResultsTreeActions;
import com.google.jessewilson.codesearch.ui.tree.ResultsForOneQuery;
import com.google.jessewilson.codesearch.util.Progress;
import com.google.inject.Provider;
import com.google.inject.Inject;

import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;

import java.awt.*;

import javax.swing.*;

/**
 * Show a single {@link QueryResponse}.
 *
 * @author jessewilson
 */
class ResultsPanel extends JPanel {

  private final ResultsPanelContext<ResultsPanel> panelContext;

  private final QueryResponse results;
  private final ResultsForOneQuery resultsForOneQuery;
  private final ResultsTreeActions resultsTreeActions;

  private final JProgressBar progressBar;

  public ResultsPanel(
        ResultsPanelContext<ResultsPanel> panelContext,
        QueryResponse results,
        CombineQueriesAction.Factory combineQueriesActionFactory) {
    super(new BorderLayout());
    this.panelContext = panelContext;
    this.results = results;

    // build the results display
    resultsForOneQuery = new ResultsForOneQuery(results);
    resultsForOneQuery.addActionsProvider(panelContext.getResultActionsProvider());

    // build the actions
    this.resultsTreeActions = new ResultsTreeActions(
        resultsForOneQuery.getTreeList(), resultsForOneQuery.getTable(),
        panelContext.getResultActionsProvider(), results);

    // display the progress on a progress bar
    progressBar = new JProgressBar();
    results.getProgress().addListener(new Progress.Listener() {
      public void progressUpdated(Progress progress) {
        progressBar.setIndeterminate(progress.isBusy());
      }
    });

    DefaultActionGroup group = new DefaultActionGroup("CodeSearch_Tree", false);
    group.add(new ClosePanelAction());
    group.add(new ExpandAllAction());
    group.add(new CollapseAllAction());
    group.add(new PreviousResultAction());
    group.add(new NextResultAction());
    group.add(combineQueriesActionFactory.create(panelContext, results, "Intersect With", "/com/google/jessewilson/codesearch/icons/intersection.png", ResultsCombiner.intersection));
    group.add(combineQueriesActionFactory.create(panelContext, results, "Union With", "/com/google/jessewilson/codesearch/icons/union.png", ResultsCombiner.union));

    ActionToolbar actions = ActionManager.getInstance().createActionToolbar("Sidebar", group, false);

    add(actions.getComponent(), BorderLayout.WEST);
    add(resultsForOneQuery.getComponent(), BorderLayout.CENTER);
    add(progressBar, BorderLayout.SOUTH);
  }

  public QueryResponse getResults() {
    return results;
  }

  /**
   * Dispose resources allocated by this panel.
   */
  public void dispose() {
    resultsForOneQuery.dispose();
  }

  private class ClosePanelAction extends AnAction {
    public ClosePanelAction() {
      super("Close", "Close", new ImageIcon(ExpandAllAction.class.getClassLoader().getResource("actions/cancel.png")));
    }
    public void actionPerformed(AnActionEvent e) {
      panelContext.close(ResultsPanel.this);
    }
  }
  private class ExpandAllAction extends AnAction {
    public ExpandAllAction() {
      super("Expand All", "Expand All", new ImageIcon(ExpandAllAction.class.getClassLoader().getResource("icons/inspector/expandall.png")));
    }
    public void actionPerformed(AnActionEvent e) {
      resultsTreeActions.expandAll();
    }
  }
  private class CollapseAllAction extends AnAction {
    public CollapseAllAction() {
      super("Collapse All", "Collapse All", new ImageIcon(ExpandAllAction.class.getClassLoader().getResource("icons/inspector/collapseall.png")));
    }
    public void actionPerformed(AnActionEvent e) {
      resultsTreeActions.collapseAll();
    }
  }
  private class PreviousResultAction extends AnAction {
    public PreviousResultAction() {
      super("Previous Result", "Previous Result", new ImageIcon(ExpandAllAction.class.getClassLoader().getResource("actions/previousOccurence.png")));
    }
    public void actionPerformed(AnActionEvent e) {
      resultsTreeActions.previous();
    }
  }
  private class NextResultAction extends AnAction {
    public NextResultAction() {
      super("Next Result", "Next Result", new ImageIcon(ExpandAllAction.class.getClassLoader().getResource("actions/nextOccurence.png")));
    }
    public void actionPerformed(AnActionEvent e) {
      resultsTreeActions.next();
    }
  }

  public static class Factory  {
    @Inject private CombineQueriesAction.Factory combineQueriesActionFactory;
    public ResultsPanel create(ResultsPanelContext<ResultsPanel> resultsPanelContext, QueryResponse queryResponse) {
      return new ResultsPanel(resultsPanelContext, queryResponse, combineQueriesActionFactory);
    }
  }
}
